/**
 * 封装通用的fetch请求工具
 * 基础域名: https://www.tcai.asia
 */

// 定义基础URL
const BASE_URL = 'https://www.tcai.asia';

// 请求配置接口
export interface RequestOptions extends RequestInit {
  // 是否携带凭证（cookies）
  withCredentials?: boolean;
  // 自定义请求头
  headers?: HeadersInit;
  // 请求超时时间（毫秒）
  timeout?: number;
  // 是否自动处理错误
  handleError?: boolean;
}

// 响应结构接口
export interface ApiResponse<T = any> {
  code: number;
  data: T;
  message: string;
  success: boolean;
}

// 默认请求配置
const defaultOptions: RequestOptions = {
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
  timeout: 10000, // 10秒超时
  handleError: true,
};

/**
 * 创建请求超时Promise
 * @param timeout 超时时间（毫秒）
 */
const createTimeoutPromise = (timeout: number): Promise<never> => {
  return new Promise((_, reject) => {
    setTimeout(() => {
      reject(new Error(`Request timeout after ${timeout}ms`));
    }, timeout);
  });
};

/**
 * 获取存储的token
 */
const getToken = (): string | null => {
  if (typeof window !== 'undefined') {
    return localStorage.getItem('token');
  }
  return null;
};

/**
 * 处理请求错误
 * @param error 错误对象
 * @param handleError 是否自动处理错误
 */
const handleRequestError = (error: any, handleError: boolean): never => {
  if (handleError) {
    // 这里可以添加全局错误处理，如显示错误通知
    console.error('API Request Error:', error);
    
    // 如果使用了UI库的通知组件，可以在这里调用
    // 例如: notification.error({ message: '请求错误', description: error.message });
  }
  throw error;
};

/**
 * 通用请求方法
 * @param url 请求路径
 * @param options 请求配置
 */
export async function request<T = any>(
  url: string,
  options: RequestOptions = {}
): Promise<ApiResponse<T>> {
  // 合并默认配置和自定义配置
  const mergedOptions: RequestOptions = {
    ...defaultOptions,
    ...options,
    headers: {
      ...defaultOptions.headers,
      ...options.headers,
    },
  };

  // 添加认证token（如果存在）
  const token = getToken();
  if (token) {
    mergedOptions.headers = {
      ...mergedOptions.headers,
      'Authorization': `Bearer ${token}`,
    };
  }

  // 构建完整URL
  const fullUrl = url.startsWith('http') ? url : `${BASE_URL}${url}`;

  try {
    // 创建请求Promise和超时Promise
    const fetchPromise = fetch(fullUrl, mergedOptions);
    const timeoutPromise = createTimeoutPromise(mergedOptions.timeout || defaultOptions.timeout);

    // 使用Promise.race竞争，谁先完成就用谁的结果
    const response = await Promise.race([fetchPromise, timeoutPromise]);
    
    // 检查HTTP状态码
    if (!response.ok) {
      const errorData = await response.json().catch(() => ({}));
      const error = new Error(
        errorData.message || `HTTP error! Status: ${response.status}`
      );
      return handleRequestError(error, mergedOptions.handleError || defaultOptions.handleError);
    }

    // 解析响应JSON
    const data = await response.json();
    
    // 检查API响应状态码
    if (data.code !== 0 && data.code !== 200) {
      const error = new Error(data.message || 'API request failed');
      return handleRequestError(error, mergedOptions.handleError || defaultOptions.handleError);
    }

    return data;
  } catch (error) {
    return handleRequestError(error, mergedOptions.handleError || defaultOptions.handleError);
  }
}

/**
 * GET请求
 * @param url 请求路径
 * @param params 查询参数
 * @param options 请求配置
 */
export async function get<T = any>(
  url: string,
  params?: Record<string, any>,
  options?: RequestOptions
): Promise<ApiResponse<T>> {
  // 构建查询字符串
  const queryString = params
    ? `?${new URLSearchParams(params).toString()}`
    : '';
  
  return request<T>(`${url}${queryString}`, {
    method: 'GET',
    ...options,
  });
}

/**
 * POST请求
 * @param url 请求路径
 * @param data 请求体数据
 * @param options 请求配置
 */
export async function post<T = any>(
  url: string,
  data?: any,
  options?: RequestOptions
): Promise<ApiResponse<T>> {
  return request<T>(url, {
    method: 'POST',
    body: data ? JSON.stringify(data) : undefined,
    ...options,
  });
}

/**
 * PUT请求
 * @param url 请求路径
 * @param data 请求体数据
 * @param options 请求配置
 */
export async function put<T = any>(
  url: string,
  data?: any,
  options?: RequestOptions
): Promise<ApiResponse<T>> {
  return request<T>(url, {
    method: 'PUT',
    body: data ? JSON.stringify(data) : undefined,
    ...options,
  });
}

/**
 * DELETE请求
 * @param url 请求路径
 * @param options 请求配置
 */
export async function del<T = any>(
  url: string,
  options?: RequestOptions
): Promise<ApiResponse<T>> {
  return request<T>(url, {
    method: 'DELETE',
    ...options,
  });
}

// 导出默认对象
const api = {
  get,
  post,
  put,
  delete: del,
  request,
};

export default api;
